package com.Education.util;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.Education.pojo.User;
import com.Education.server.UserService;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HttpClientUtils {

    @Autowired
    UserService userService;

    public static HttpClientUtils httpClientUtils;


    @PostConstruct
    public void init() {
        httpClientUtils = this;
        //httpClientUtils.userService = this.userService;
    }


    /**
     * 忽略服务器证书，采用信任策略1
     *
     * @return
     */
    public static SSLConnectionSocketFactory getSSLConnectionSocket() {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    //return new X509Certificate[0];
                    return null;
                }

            };
            ctx.init(null, new TrustManager[] { tm }, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(
                    ctx, NoopHostnameVerifier.INSTANCE);
            /*
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(ssf).build();

            return httpclient;
             */

            return ssf;
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 忽略服务器证书，采用信任策略2
     *
     * @return
     */
    private static HttpClientConnectionManager getHttpClientConnectionManager() {
        try {
            // 相信自己的CA和所有自签名的证书
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null,
                    (arg0, arg1) -> true).build();
            // 只允许使用TLSv1协议
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
                    new String[]{"TLSv1"}, null,
                    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            Registry registry = RegistryBuilder.create().register("http",
                    PlainConnectionSocketFactory.INSTANCE).
                    register("https", sslsf).build();
            return new PoolingHttpClientConnectionManager(registry);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    public static HttpClientSession getHttpClient(String username){

        //最好使用static修饰，以保证用同一个client对象处理请求，以保存进度
        //CloseableHttpClient client = HttpClients.createDefault();

        //此二种都是新建一个默认的httpClient对象。可以在第二种方法里添加一些网络访问选项设置。
        //CloseableHttpClient httpClient=HttpClients.custom().build();

        //忽略服务器证书
        SSLConnectionSocketFactory ssl = getSSLConnectionSocket();

        //配置CookieStore
        CookieStore cookieStore = null;
        if (StringUtils.isNotBlank(username)) {
            //String JSESSIONID = httpClientUtils.userService.getUserByName(username).getCookie();
            //判断用户是否存在数据库过，再获取cookie
            User user = httpClientUtils.userService.getUserByName(username);
            if (user != null){
                String JSESSIONID = user.getJSESSIONID();
                String route = user.getRoute();
                if (JSESSIONID != null) {
                    cookieStore = new BasicCookieStore();
                    BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", JSESSIONID);
                    cookie.setDomain("jw.jluzh.edu.cn");
                    cookie.setPath("/");
                    BasicClientCookie cookie2 = new BasicClientCookie("route", route);
                    cookie2.setDomain("jw.jluzh.edu.cn");
                    cookie2.setPath("/");
                    cookieStore.addCookie(cookie);
                    cookieStore.addCookie(cookie2);
                }
            }else {
                cookieStore = new BasicCookieStore();
            }

        }else {
            cookieStore = new BasicCookieStore();
        }

        //List<Cookie> cookies = cookieStore.getCookies();
        //System.out.println("cookiesByMysql:"+cookies);

        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(ssl)
                .setDefaultCookieStore(cookieStore)
                .build();

        return new HttpClientSession(httpClient, cookieStore);
    }


    /**
     * 获取HttpClientSession对象
     *
     * @param sessionId
     * @param automaticRedirect
     * @param timeOut
     * @return
     */
    public static HttpClientSession getHttpClient2(String sessionId, boolean automaticRedirect, int timeOut) {
        timeOut = timeOut * 1000;
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
        //设置超时时间
        requestConfigBuilder.setSocketTimeout(timeOut).setConnectTimeout(timeOut)
                .setConnectionRequestTimeout(timeOut);
        //自动检测StaleConnection
        requestConfigBuilder.setStaleConnectionCheckEnabled(true);
        //配置默认请求配置
        httpClientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
        //设置连接管理器
        httpClientBuilder.setConnectionManager(getHttpClientConnectionManager());
        //设置自动重定向配置
        if (!automaticRedirect) {
            httpClientBuilder.disableRedirectHandling();
        }
        //配置CookieStore
        CookieStore cookieStore = null;
        if (StringUtils.isNotBlank(sessionId)) {
            //cookieStore = cookieStoreDao.QueryCookieStore(sessionId);
            if (cookieStore == null) {
                cookieStore = new BasicCookieStore();
            }
            httpClientBuilder.setDefaultCookieStore(cookieStore);
        }
        return new HttpClientSession(httpClientBuilder.build(), cookieStore);
    }




}
